﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using RestServices.Response.SkyDrive;

namespace RestServices
{
    public class SkyDriveService
    {
        private WebClient _client;
        private Uri _address;
        private string _filePath;
        private bool _uploadCompleted;
        private bool _uploadStarted;
        private bool _status;
        public event UploadProgressChangedEventHandler Progress;
        public event UploadFileCompletedEventHandler Completed;


        //public string CreateRequestCode(string clientID, string ClientSecret)
        //{
        //    //https://login.live.com/oauth20_authorize.srf?client_id=CLIENT_ID&scope=wl.signin%20wl.skydrive_update&response_type=RESPONSE_TYPE&redirect_uri=REDIRECT_URL
        //    string UrlRequest = "https://login.live.com/oauth20_authorize.srf?client_id=" +
        //                         clientID +
        //        //"&client_secret=" + ClientSecret +
        //        //"&scope=wl.signin%20wl.skydrive_update%20wl.offline_access&response_type=code&redirect_uri=https://login.live.com/oauth20_desktop.srf";
        //        //"&scope=wl.signin%20wl.basic%20wl.offline_access&response_type=code&redirect_uri=https://oauth.live.com/desktop";
        //                         "&scope=wl.signin%20wl.basic%20wl.offline_access" +
        //                         "&redirect_uri=https://oauth.live.com/desktop&grant_type=authorization_code";

        //    return (UrlRequest);
        //}

        //public string CreateRequestRefreshCode(string clientID, string ClientSecret)
        //{
        //    //client_id=CLIENT_ID&redirect_uri=REDIRECT_URL&client_secret=CLIENT_SECRET&code=AUTHORIZATION_CODE&grant_type=authorization_code
        //    string UrlRequest = "https://login.live.com/oauth20_authorize.srf?client_id=" +
        //                         clientID +
        //        //"&client_secret=" + ClientSecret +
        //        //"&scope=wl.signin%20wl.skydrive_update%20wl.offline_access&response_type=code&redirect_uri=https://login.live.com/oauth20_desktop.srf";
        //        //"&scope=wl.signin%20wl.basic%20wl.offline_access&response_type=code&redirect_uri=https://oauth.live.com/desktop";
        //                         "&scope=wl.signin%20wl.basic%20wl.offline_access&response_type=code&redirect_uri=https://oauth.live.com/desktop&grant_type=authorization_code";

        //    return (UrlRequest);
        //}

        public string RequestFirstFolder(string token)
        {
            //https://login.live.com/oauth20_authorize.srf?client_id=CLIENT_ID&scope=wl.signin%20wl.skydrive_update&response_type=RESPONSE_TYPE&redirect_uri=REDIRECT_URL
            string UrlRequest = "https://apis.live.net/v5.0/me/skydrive?access_token=" + token;
            return (UrlRequest);
        }

        public string RequestFilesFolders(string folderID, string token)
        {
            //https://login.live.com/oauth20_authorize.srf?client_id=CLIENT_ID&scope=wl.signin%20wl.skydrive_update&response_type=RESPONSE_TYPE&redirect_uri=REDIRECT_URL
            string UrlRequest = "https://apis.live.net/v5.0/" + folderID + "/files?access_token=" + token;
            return (UrlRequest);
        }

        public string RequestUpload(string folderId, string token)
        {
            //https://login.live.com/oauth20_authorize.srf?client_id=CLIENT_ID&scope=wl.signin%20wl.skydrive_update&response_type=RESPONSE_TYPE&redirect_uri=REDIRECT_URL
            //string UrlRequest = "https://apis.live.net/v5.0/me/skydrive/files?access_token=" + token;
            string UrlRequest = "https://apis.live.net/v5.0/" + folderId + "/files?access_token=" + token;
            return (UrlRequest);
        }

        //Obter folders: GET https://apis.live.net/v5.0/me/skydrive?access_token=ACCESS_TOKEN
        //Obter tudo de um folder: GET https://apis.live.net/v5.0/folder.a6b2a7e8f2515e5e/files?access_token=ACCESS_TOKEN

        public string MakeRequestPostForCode(string requestUrl)
        {
            try
            {
                HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = 0;
                using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                {
                    if (response.StatusCode != HttpStatusCode.OK)
                        throw new Exception(String.Format(
                        "Server error (HTTP {0}: {1}).",
                        response.StatusCode,
                        response.StatusDescription));

                    Encoding enc = System.Text.Encoding.GetEncoding(1252);
                    StreamReader loResponseStream = new
                      StreamReader(response.GetResponseStream(), enc);

                    string Response = loResponseStream.ReadToEnd();

                    loResponseStream.Close();
                    return Response;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return "";
            }
        }

        public string RequestAccessToken(string oauthUrl)
        {
            try
            {
                string postContent = oauthUrl.Substring(oauthUrl.IndexOf('?') + 1);
                string url = oauthUrl.Substring(0, oauthUrl.IndexOf('?'));
                HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
                request.ContentLength = postContent.Length;

                using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
                {
                    writer.Write(postContent,0,postContent.Length);
                }

                HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                if (response != null)
                {
                    if (response.StatusCode != HttpStatusCode.OK)
                        throw new Exception(String.Format(
                        "Server error (HTTP {0}: {1}).",
                        response.StatusCode,
                        response.StatusDescription));

                    Encoding enc = System.Text.Encoding.GetEncoding(1252);
                    StreamReader loResponseStream = new
                      StreamReader(response.GetResponseStream(), enc);

                    string Response = loResponseStream.ReadToEnd();

                    loResponseStream.Close();
                    return Response;
                }
                return "";
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return "";
            }
        }

        public bool StatusOk
        {
            get
            {
                return _status;
            }
        }

        public bool IsCompleted
        {
            get
            {
                return _uploadCompleted;
            }
        }

        public bool IsStarted
        {
            get
            {
                return _uploadStarted;
            }
        }

        public void UploaderInitialize(string address, string filePath)
        {
            _client = new WebClient();
            _address = new Uri(address);
            _filePath = filePath;
            _client.UploadProgressChanged += FileUploadProgressChanged;
            _client.UploadFileCompleted += FileUploadFileCompleted;
        }

        public void FileUploadFileCompleted(object sender, UploadFileCompletedEventArgs e)
        {
            _status = (e.Cancelled || e.Error == null) ? false : true;
            _uploadCompleted = true;
            UploadFileCompletedEventHandler caller = new UploadFileCompletedEventHandler(this.Completed);
            caller.BeginInvoke(this, e, null, null);
            //Completed(this, e);
        }

        public void FileUploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
        {
            if (e.ProgressPercentage % 10 == 0)
            {
                //This writes the pecentage data uploaded and downloaded
                Console.WriteLine("Send: {0}, Received: {1}", e.BytesSent, e.BytesReceived);
                //You can have a delegate or a call back to update your UI about the percentage uploaded
                //If you don't have the condition (i.e e.ProgressPercentage % 10 == 0 )for the pecentage of the process 
                //the callback will slow you upload process down
            }
            UploadProgressChangedEventHandler caller = new UploadProgressChangedEventHandler(this.Progress);
            caller.BeginInvoke(this, e, null, null);             
        }

        public bool Upload()
        {

            if (!_uploadStarted)
            {
                _uploadStarted = true;
                _client.UploadFileAsync(_address, _filePath);
            }
            while (!_uploadCompleted)
            {
                Thread.Sleep(1000);
            }
            return _status;
        }

        public void Dispose()
        {
            _client.Dispose();
        }
    }
}
